package com.bluemartini.jmx.mbean;

import com.bluemartini.dna.BMLog;
import com.bluemartini.dna.DNAList;
import com.bluemartini.util.HTMLVersionUtil;

/**
 * Expose BM cache statistics as MBean for management
 * 
 * @author Yannick Robin
 *
 */
public class Cache implements CacheMBean {
	
	private static DNAList dnaCacheStats_;
	private static long lastCheckTime;
	private final static int CACHE_STATS_CHECK_SECONDS = 5*1000; //5 seconds

	private String name;
	public Cache(String name)
	{
		this.name = name;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public String getType()
	{
		DNAList dnaCache = getCacheStats("name");
		if (dnaCache == null)
			return "";
		return dnaCache.getString("type", "");
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int getCheckSeconds() {
		DNAList dnaCache = getCacheStats(name);
		if (dnaCache == null)
			return -1;
		return dnaCache.getInteger("checkSeconds", -1);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int getSize()
	{
		DNAList dnaCache = getCacheStats(name);
		if (dnaCache == null)
			return 0;
		return dnaCache.getInteger("size", 0);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int getSofLimit()
	{
		DNAList dnaCache = getCacheStats(name);
		if (dnaCache == null)
			return 0;
		return dnaCache.getInteger("softLimit", dnaCache.getInteger("maxSize", 0));
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int getHardLimit()
	{
		DNAList dnaCache = getCacheStats(name);
		if (dnaCache == null)
			return 0;
		return dnaCache.getInteger("hardLimit", getSofLimit());
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int getLRUSize()
	{
		DNAList dnaCache = getCacheStats(name);
		if (dnaCache == null)
			return 0;
		return dnaCache.getInteger("lruSize", dnaCache.getInteger("size", 0));
	}
	
	/**
	 * {@inheritDoc}
	 */
	public double getHitRatio()
	{
		DNAList dnaCache = getCacheStats(name);
		if (dnaCache == null)
			return 0;
		return dnaCache.getDouble("Instrument:hit ratio percent", 0);
	}
	
	/**
	 * To calculate cache size is expensive, this method ensures 
	 * cache stats will not be recalculated for each call.
	 * 
	 * @param name
	 * @return
	 */
	protected static synchronized DNAList getCacheStats(String name)
	{ 
		long currentTime = System.currentTimeMillis();
		if (currentTime - lastCheckTime > CACHE_STATS_CHECK_SECONDS)
		{
			dnaCacheStats_ = HTMLVersionUtil.getCacheStats();
			BMLog.log(BMLog.COMPONENT_SYSTEM, 2, "BM JMX: Refresh cache stats");
			lastCheckTime = currentTime;
		}
		
		return dnaCacheStats_.getList(name);
	}
}
